Rust memory allocation
libc::mmap (Low-level system memory mapping)
use libc::{MAP_ANONYMOUS, MAP_PRIVATE, PROT_READ, PROT_WRITE, mmap, munmap};
use std::ptr;
fn main() {
let size = 1024 * 1024; // 1MB
// Request memory-aligned allocation (page size)
let addr = unsafe {
mmap(
ptr::null_mut(), // Address hint (none)
size, // Allocation size
PROT_READ | PROT_WRITE, // Read/write permissions
MAP_PRIVATE | MAP_ANONYMOUS, // Private anonymous memory
-1, // File descriptor (not used)
0, // Offset
)
};
if addr == libc::MAP_FAILED {
panic!("mmap failed");
}
// Use the memory...
unsafe {
let slice = std::slice::from_raw_parts_mut(addr as *mut u8, size);
slice.fill(0xAA);
println!("{:?}", &slice[0..10]);
}
// Cleanup
unsafe {
munmap(addr, size);
}
}
When to use:
Need allocations ≥128KB (avoids heap fragmentation)
Require specific page alignment (e.g., hardware buffers)
Share memory between processes
Memory-mapped files
Custom allocator implementations
libc::aligned_alloc
(C11-style aligned allocation)
use libc::{aligned_alloc, free};
fn main() {
let size = 1024; // 1KB
let alignment = 128; // Must be power-of-2 and multiple of sizeof(void*)
let ptr = unsafe { aligned_alloc(alignment, size) };
if ptr.is_null() {
panic!("aligned_alloc failed");
}
// Use memory...
unsafe {
let slice = std::slice::from_raw_parts_mut(ptr as *mut u8, size);
slice.fill(0xBB);
println!("{:?}", &slice[0..10]);
}
// Free memory
unsafe {
free(ptr);
}
}
When to use:
Need specific alignments > 16 bytes
Interoperate with C libraries requiring custom alignment
Hardware buffers (DMA, GPU)
SIMD data alignment requirements
When alignment requirements exceed default allocator capabilities
std::alloc::alloc
(Rust Global Allocator)
use std::alloc::{Layout, alloc, dealloc};
fn main() {
let size = 1024;
let alignment = 8; // Must be power-of-two
let layout = Layout::from_size_align(size, alignment).expect("Invalid layout");
let ptr = unsafe { alloc(layout) };
if ptr.is_null() {
panic!("Allocation failed");
}
// Use memory...
unsafe {
let slice = std::slice::from_raw_parts_mut(ptr, size);
slice.fill(0xCC);
println!("{:?}", &slice[0..10]);
}
// Deallocate
unsafe {
dealloc(ptr, layout);
}
}
When to use:
General-purpose Rust allocations
Integration with Rust's ownership system
When implementing custom allocators (via
GlobalAlloc
trait)Most standard use cases (collections, etc.)
When alignment ≤ platform's default (usually 8-16 bytes)
Comparison
libc::mmap
- Use Case: Large allocations, shared memory, custom allocators, mmap files
- Alignment Requirement: Page-aligned (usually 4K)
- Size Requirement: ≥128KB ideal
- Deallocation: munmap
libc::aligned_alloc
- Use Case: Special hardware/SIMD alignment, C interoperability, >32-byte alignment
- Alignment Requirement: User-specified (power-of-2)
- Size Requirement: multiple of alignment
- Deallocation: free
std::alloc::alloc
- Use Case: General Rust allocations, default heap memory
- Alignment Requirement: ≤ Platform default (usually 16B)
- Size Requirement: Any size
- Deallocation: dealloc
with Layout
Recommended Practice:
Default Choice: Use Rust's standard allocator (
Vec
,Box
, etc.) where possibleSpecial Alignment: Use
aligned_alloc
for alignment > 32 bytesLarge Blocks: Use
mmap
for allocations > 1MBCustom Allocators: Implement
GlobalAlloc
trait wrapping these methods